package link.jfire.socket.socketserver.transfer.handler.accept;

import java.nio.channels.AsynchronousCloseException;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.CompletionHandler;
import javax.annotation.Resource;
import link.jfire.baseutil.simplelog.ConsoleLogFactory;
import link.jfire.baseutil.simplelog.Logger;
import link.jfire.core.JfireContext;
import link.jfire.socket.socketserver.bus.ServerChannelInfo;
import link.jfire.socket.socketserver.transfer.server.AioServer;
import link.jfire.socket.socketserver.transfer.server.ServerConfig;
import link.jfire.socket.socketserver.transfer.server.ServerStatus;

@Resource
public class AcceptHandler implements CompletionHandler<AsynchronousSocketChannel, Object>
{
    @Resource
    private AioServer    aioServer;
    @Resource
    private JfireContext context;
    @Resource
    private ServerStatus serverStatus;
    private Logger       logger           = ConsoleLogFactory.getLogger();
    private String       msgResourcesName = ServerChannelInfo.class.getName();
    @Resource
    private ServerConfig config;
    
    @Override
    public void completed(AsynchronousSocketChannel socketChannel, Object attachment)
    {
        try
        {
            ServerChannelInfo channelInfo = (ServerChannelInfo) context.getBean(msgResourcesName);
            channelInfo.setReadTimeout(config.getReadTiemout());
            channelInfo.setSocketChannel(socketChannel);
            channelInfo.setWaitTimeout(config.getWaitTimeout());
            serverStatus.add(channelInfo);
            logger.debug("开启一个新通道{}", channelInfo.getAddress());
            channelInfo.startReadWait();
            aioServer.getServerSocketChannel().accept(null, this);
        }
        catch (Exception e)
        {
            logger.error("注册异常", e);
        }
    }
    
    @Override
    public void failed(Throwable exc, Object attachment)
    {
        if (exc instanceof AsynchronousCloseException)
        {
            logger.info("服务端监听链接被关闭");
        }
        else if (exc instanceof ClosedChannelException)
        {
            logger.info("服务端监听链接被关闭");
        }
        else
        {
            logger.error("链接异常关闭", exc);
        }
        Thread.currentThread().interrupt();
    }
    
}
